package com.sensor.work.service;

import com.sensor.work.config.ClimaticExtremumConfig;
import com.sensor.work.config.DataBoundValueConfig;
import com.sensor.work.entity.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;

import static com.sensor.work.config.DataBoundValueConfig.isExceed;

@Service
@Slf4j
public class QcServer {

    @Autowired
    private IQcDataService qcDataService;


    public boolean  deviceQcControl(PudongDeviceData map, PudongDeviceConfig deviceInfo){
        log.info("质控的数据#{}",map);

        long statTime = System.currentTimeMillis();
        List<QcData> list = new LinkedList<>();
        Field[] declaredFields = PudongDeviceData.class.getDeclaredFields();
        boolean isSave = false;
//        log.info("质控数据#{}",map.toString());
        for (Field declaredField : declaredFields) {
            Object fieldObj = null;

            try {

            //质控流程
            if (formatCheck(map,list,declaredField,deviceInfo)){
                fieldObj = declaredField.get(map);
//                log.error("字段#{}",declaredField.getName());
                if (missingDataCheck(map,list,declaredField,deviceInfo,fieldObj)){
                    if (thresholdValueCheck(map,list,declaredField,deviceInfo,fieldObj)){

                        stationExtremumParameterCheck(map,list,declaredField,deviceInfo,fieldObj);
                        internalConsistencyCheck(map,list,declaredField,deviceInfo,fieldObj);
                        timeConsistencyCheck(map,list,declaredField,deviceInfo,fieldObj);
                        isSave = true;
                    }
                }
            }
            } catch (IllegalAccessException e) {

                throw new RuntimeException(e);
            }
        }
        for (QcData qcData : list) {
            log.info(qcData.toString());
        }
        boolean b = qcDataService.saveBatch(list);
        long endTime = System.currentTimeMillis();

        log.info("用时:#{}毫秒",(endTime-statTime));

    return isSave;
    }


    /**
     * 格式检查
     * @param data 数据
     * @return
     */
    public boolean  formatCheck(PudongDeviceData data, List<QcData> list ,Field field,PudongDeviceConfig deviceInfo){
//        log.info(field.getName()+"格式检查");
        if (data == null) {
            return false;
        }
        if (field.getName().equals("id")||field.getName().equals("ttDict")||field.getName().equals("createTime")||field.getName().equals("serialVersionUID")||field.getName().equals("deviceNo")||field.getName().equals("timestamp")){
            return false;
        }

            field.setAccessible(true);
        return true;
    }



    /**
     * 缺测检查
     * @param data 数据  list qc列表 field字段属性  deviceInfo设备详情  fieldObj 字段值
     * @return
     */
    public boolean  missingDataCheck(PudongDeviceData data, List<QcData> list ,Field field,PudongDeviceConfig deviceInfo,Object fieldObj){

        if (fieldObj==null||fieldObj.equals("-500")||fieldObj.equals("////")||fieldObj.equals(-500.0)||fieldObj.equals(-500)){
            QcData qcData = new QcData();
            qcData.setSnCode(data.getDeviceNo());
            qcData.setExceptionField(field.getName());
            qcData.setDevicePoint(deviceInfo.getSensorPoint());
            qcData.setExceptionValue("缺测");
            qcData.setDataId(data.getId());
            qcData.setDeviceName(deviceInfo.getName());
            qcData.setQcCode("8");
            qcData.setReason("数据为"+fieldObj);
            qcData.setDataType("历史数据");
            qcData.setTt(data.getTT());
            list.add(qcData);
//            log.info("缺测新增");
            return false;
        }
        return true;
    }


    /**
     * 界限值检查
     * @param  data 数据  list qc列表 field字段属性  deviceInfo设备详情  fieldObj 字段值
     * @return 是否超过界限检查
     */
    public boolean  thresholdValueCheck(PudongDeviceData data, List<QcData> list ,Field field,PudongDeviceConfig deviceInfo,Object fieldObj){
//        log.info("界限值检查");
        boolean exceed = isExceed(Float.parseFloat(fieldObj.toString()), field.getName());
        if (!exceed){
            addQcData(data,list,field,deviceInfo,fieldObj,"2","超过界限检查");
        }

        return exceed;

    }
    public void  addQcData(PudongDeviceData data, List<QcData> list ,Field field,PudongDeviceConfig deviceInfo,Object fieldObj,String qcCode,String arg){
        QcData qcData = new QcData();
        qcData.setSnCode(data.getDeviceNo());
        qcData.setExceptionField(field.getName());
        qcData.setDevicePoint(deviceInfo.getSensorPoint());
        qcData.setExceptionValue(fieldObj.toString());
        qcData.setDataId(data.getId());
        qcData.setDeviceName(deviceInfo.getName());
        qcData.setQcCode(qcCode);
        qcData.setReason("数据为"+fieldObj+arg);
        qcData.setDataType("历史数据");
        qcData.setTt(data.getTT());
        list.add(qcData);
    }




    /**
     *  气候极值检查
     * @param
     * @return
     */
    public boolean  stationExtremumParameterCheck(PudongDeviceData data, List<QcData> list ,Field field,PudongDeviceConfig deviceInfo,Object fieldObj){
//        log.info("气候极值检查");
        // 创建一个日历对象
        Calendar calendar = Calendar.getInstance();
        // 获取当前月份
        int month = calendar.get(Calendar.MONTH) + 1;
//        log.info("当前月份是：" + month);
        boolean exceed = ClimaticExtremumConfig.isExceed(Float.parseFloat(fieldObj.toString()), field.getName(), month);
        if (!exceed){
            addQcData(data,list,field,deviceInfo,fieldObj,"1","超过气候极值检查");
        }
        return exceed;
    }


    /**
     *  内部一致性检查
     * @param
     * @return
     */
    public boolean  internalConsistencyCheck(PudongDeviceData data, List<QcData> list ,Field field,PudongDeviceConfig deviceInfo,Object fieldObj ){
//        log.info("内部一致性检查");
//        log.info(data.toString());
        return true;
    }

    /**
     *  时间一致性检查
     * @param
     * @return
     */
    public boolean  timeConsistencyCheck(PudongDeviceData data, List<QcData> list ,Field field,PudongDeviceConfig deviceInfo,Object fieldObj ){
//        log.info("时间一致性检查");
//        log.info(data.toString());
        return true;
    }

}
